# !/usr/bin/env python
# -*- coding: utf-8 -*-
# @File  : 手写数字识别_KNN实现分类（特征预处理+交叉验证网格搜索）.py
# @Author: dongguangwen
# @Date  : 2025-01-20 21:46
# 0.导入工具包
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.neighbors import KNeighborsClassifier


# 1.获取数据
data = pd.read_csv('./data/手写数字识别.csv')
x = data.iloc[:, 1:]
y = data.iloc[:, 0]

# 特征归一化
transform = MinMaxScaler()
x = transform.fit_transform(x)
# x = x / 255.

# 数据集划分
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, stratify=y, random_state=22)

# 模型实例化
model = KNeighborsClassifier(n_neighbors=1)

# 网格搜索交叉验证
param_grid = {
    'n_neighbors': [3, 5, 7, 9, 11]
}
model = GridSearchCV(estimator=model, param_grid=param_grid, cv=4)
model.fit(x_train, y_train)
print(model.best_estimator_)

# 模型训练
model = KNeighborsClassifier(n_neighbors=3)
model.fit(x_train, y_train)

# 模型预测
img = plt.imread('./data/digit.png')
# img = img.reshape(1, -1) / 255.  # 黑白图片时使用
img = img[:, :, 1].reshape(1, -1) / 255.  # 彩色图片时需要转为一维通道
print(model.predict(img))

# 模型评估
print(model.score(x_test, y_test))

"""
KNeighborsClassifier(n_neighbors=3)
[1]
0.965
"""